package com.dhsc.util;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

/**
 * @ClassName:  RSAEncrypt
 * @Description: rsa加密解密
 * @date:   2020年12月24日 下午5:12:45       
 * @author: chenlong
 * @Copyright:  迅优智超
 */
public class RSAEncrypt {
	
	private RSAEncrypt()
	{
		
	}
	
	private static Map<Integer, String> keyMap = new HashMap<>();  //用于封装随机产生的公钥与私钥
	
	/** 
	 * 随机生成密钥对 
	 * @throws NoSuchAlgorithmException 
	 */  
	public static void genKeyPair() throws NoSuchAlgorithmException {  
		// KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象  
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");  
		// 初始化密钥对生成器，密钥大小为96-1024位  
		keyPairGen.initialize(2048,new SecureRandom());  
		// 生成一个密钥对，保存在keyPair中  
		KeyPair keyPair = keyPairGen.generateKeyPair();  
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥  
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥  
		String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));  
		// 得到私钥字符串  
		String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));  
		// 将公钥和私钥保存到Map
		keyMap.put(0,publicKeyString);  //0表示公钥
		keyMap.put(1,privateKeyString);  //1表示私钥
	}  
	/** 
	 * RSA公钥加密 
	 *  
	 * @param str 
	 *            加密字符串
	 * @param publicKey 
	 *            公钥 
	 * @return 密文 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeySpecException 
	 * @throws NoSuchPaddingException 
	 * @throws InvalidKeyException 
	 * @throws UnsupportedEncodingException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws Exception 
	 *             加密过程中的异常信息 
	 */  
	public static String encrypt( String str) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		//base64编码的公钥
		String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIsQ5vxx4FlC09xKiahBfSNo5b0Wg8fkGzRWv7EMWhRim4p9DYsBU8arg2bRpxSU0k0NTl3nlfeAmQln6pTCUo2DV1bE3rfUFBRznYUZLJVIVtRcMSnWUs81TdCVaqBIpn+KIXRE6JDYBs+b0wq+yTFBkZwt2+CcpwWQFaOehTlwIDAQAB";
		byte[] decoded = Base64.decodeBase64(publicKey);
		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
		//RSA加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
	}

	/** 
	 * RSA私钥解密
	 *  
	 * @param str 
	 *            加密字符串
	 * @param privateKey 
	 *            私钥 
	 * @return 铭文
	 * @throws UnsupportedEncodingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeySpecException 
	 * @throws NoSuchPaddingException 
	 * @throws InvalidKeyException 
	 * @throws BadPaddingException 
	 * @throws IllegalBlockSizeException 
	 * @throws Exception 
	 *             解密过程中的异常信息 
	 */  
	public static String decrypt(String str) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		
		String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIixDm/HHgWULT3EqJqEF9I2jlvRaDx+QbNFa/sQxaFGKbin0NiwFTxquDZtGnFJTSTQ1OXeeV94CZCWfqlMJSjYNXVsTet9QUFHOdhRkslUhW1FwxKdZSzzVN0JVqoEimf4ohdETokNgGz5vTCr7JMUGRnC3b4JynBZAVo56FOXAgMBAAECgYB/mZi6a4vw9UPOV1h09T4vc9IskCzX25yFNxb3xc5XIGIuCCoDPUx1m8HevLZkbmLfLTqwYp+2qR10pagTbgt42RGRjUsZ7tQyC1ZJhr+bPULamsX4OV3ivulGtd0EhtHoWh3GY4SPAbO5eSr03uY2tkhL9fKnyaLDsUDZB+M78QJBAMqJTHd+WqDhFoKMNZgrE0TWSYVnC56O9+uKvOsgITZOU/N0uTosO+7XJH9tVjLGUQcHPOs7rHVCwu4FR5UuMLMCQQCsxjOoGyIMAvdK2VoPYBZI3oizOeCmwJkNu0Fa4ZZSfzODQ61SgVzegniWac463vsN+CszUCmDrkt97guPaPuNAkEAxPCIyFC282SrrLmFi7em/vKXfv5aEA3ZCNJZLRCK+vFjNII1cll81Zuhw76faLPqKjlhhSL7aPJH9YZwuqC1fQJAC1i468Fcaw2G0BOWJoxY6lAzChIy/sCHTK+PizhlduWDrIs1RsXYI4TOBpLMSHF8a15w99273DoGGy8W80QhwQJAfLQGHt8kTtEnGoRijh2KzdV8/m2bowZvUmPKU4IbhwpMgXm/kkmYJok2Wx6eAy9L3N0STqAMMWXDJY/Qx4kLQg==";
		//64位解码加密后的字符串
		byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
		//base64编码的私钥
		byte[] decoded = Base64.decodeBase64(privateKey);  
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));  
		//RSA解密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		return new String(cipher.doFinal(inputByte));
	}

}
